/**
 * @file server.cc
 * @author zziywang (zziywang@163.com)
 * @brief { life is too short to learn cpp! }
 * @version 3.0
 * @date 2022-05-09
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "TcpServer.hh"
#include "ThreadPool.hh"
#include <functional>
#include <iostream>
using namespace std;
using namespace snow;

// #define DEBUG

class MyTask
{
public:
    MyTask(const string &msg, const TcpConnectionPtr &tcp)
        : msg_(msg), tcp_(tcp) {}

    void process()
    {
#ifdef DEBUG
        cout << ">>> " << tls::threadName << " is working..." << endl;
        cout << ">>> MyTask::process()  " << endl;
#endif // DEBUG
       //由线程池的线程(计算线程)完成数据的发送,在设计上来说，是不合理的
       //数据发送的工作要交还给IO线程(Reactor所在的线程)完成
       //将send的函数的执行延迟到IO线程取操作，交给EventLoop中的loop执行。
        tcp_->sendInEventLoop(msg_);
    }

private:
    string msg_;
    TcpConnectionPtr tcp_;
};

class EchoServer
{
public:
    EchoServer(const string &ip, unsigned short port)
        : threadPool_(4, 10), tcpServer_(ip, port) {}

    void start()
    {
        threadPool_.start();
        tcpServer_.setConnectionCallBack(std::bind(&EchoServer::onConnection, this, std::placeholders::_1));
        tcpServer_.setMessageCallBack(std::bind(&EchoServer::onMessage, this, std::placeholders::_1));
        tcpServer_.setCloseCallBack(std::bind(&EchoServer::onClose, this, std::placeholders::_1));
        tcpServer_.start();
    }

    // 自定义回调函数传参
    void onConnection(const TcpConnectionPtr &ptr)
    {
        cout << ptr->printTcp() << " has connected!" << endl;
        // ptr->send("Welcome to EchoServer");
    }
    void onMessage(const TcpConnectionPtr &ptr)
    {
        cout << ">> from client " << ptr->printTcp() << endl;
        string msg = ptr->recvLine();
        cout << msg << endl;

        MyTask task(msg, ptr);
        threadPool_.addTask(
            std::bind(&MyTask::process, task) // 回显
        );
    }
    void onClose(const TcpConnectionPtr &ptr)
    {
        cout << "client " << ptr->printTcp() << " has disconnected!" << endl;
    }

private:
    ThreadPool threadPool_;
    TcpServer tcpServer_;
};

int main()
{
    EchoServer echoServer("172.25.40.81", 9999);
    echoServer.start();
    return 0;
}